package cn.shenzhenlizuosystemapp.Common.Scan;

import android.content.Context;
import android.util.Log;

import com.symbol.emdk.EMDKManager;
import com.symbol.emdk.EMDKManager.EMDKListener;
import com.symbol.emdk.EMDKResults;
import com.symbol.emdk.ProfileManager;
import com.symbol.emdk.barcode.BarcodeManager;
import com.symbol.emdk.barcode.BarcodeManager.ScannerConnectionListener;
import com.symbol.emdk.barcode.ScanDataCollection;
import com.symbol.emdk.barcode.Scanner;
import com.symbol.emdk.barcode.Scanner.DataListener;
import com.symbol.emdk.barcode.Scanner.StatusListener;
import com.symbol.emdk.barcode.ScannerConfig;
import com.symbol.emdk.barcode.ScannerException;
import com.symbol.emdk.barcode.ScannerInfo;
import com.symbol.emdk.barcode.ScannerResults;
import com.symbol.emdk.barcode.StatusData;
import com.vise.log.ViseLog;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Scan implements EMDKListener, DataListener, StatusListener, ScannerConnectionListener {

    private static Scan scan;
    private Context context;
    private OnBackCall onBackCall;
    private Scanner scanner = null;
    private BarcodeManager barcodeManager = null;
    private EMDKManager emdkManager = null;
    private ProfileManager profileManager = null;
    private EMDKManager emdkManager2 = null;

    private List<ScannerInfo> deviceList = null;

    private int scannerIndex = 1;
    private int defaultIndex = 1;

    private boolean bContinuousMode = false;

    public static Scan getScan(Context context, OnBackCall onBackCall) {
        if (scan == null) {
            synchronized (Scan.class) {
                if (scan == null) {
                    scan = new Scan(context, onBackCall);
                }
            }
        }
        return scan;
    }

    public Scan(Context context, OnBackCall onBackCall) {
        try {
            this.context = context;
            this.onBackCall = onBackCall;

            EMDKResults results = EMDKManager.getEMDKManager(context, this);
            if (results.statusCode != EMDKResults.STATUS_CODE.SUCCESS) {
                onBackCall.Error("Status 调用Emdk失败");
                return;
            }
            deInitScanner();
            initScanner();
            setTrigger();
            setDecoders();

            if (emdkManager != null) {
                barcodeManager = (BarcodeManager) emdkManager.getInstance(EMDKManager.FEATURE_TYPE.BARCODE);

                // Add connection listener
                if (barcodeManager != null) {
                    barcodeManager.addConnectionListener(this);
                }
                // Enumerate scanner devices
                enumerateScannerDevices();//适配设备支持模式
                // Set selected scanner
                setSelection(scannerIndex);
                // Initialize scanner
                initScanner();
                setTrigger();
                setDecoders();
            }
        } catch (Exception e) {
            ViseLog.i("EMDK Scan Init Exception" + e);
            e.printStackTrace();
        }
    }

    @Override
    public void onOpened(EMDKManager emdkManager) {
        Log.i("huangmin", "EMDK打开成功");

        this.emdkManager = emdkManager;

        // Acquire the barcode manager resources
        barcodeManager = (BarcodeManager) emdkManager.getInstance(EMDKManager.FEATURE_TYPE.BARCODE);

        // Add connection listener
        if (barcodeManager != null) {
            barcodeManager.addConnectionListener(this);
        }
        // Enumerate scanner devices
        enumerateScannerDevices();
        // Set default scanner
        setSelection(defaultIndex);
    }

    @Override
    public void onClosed() {
        if (emdkManager != null) {
            // Remove connection listener
            if (barcodeManager != null) {
                barcodeManager.removeConnectionListener(this);
                barcodeManager = null;
            }
            // Release all the resources
            emdkManager.release();
            emdkManager = null;
        }
        onBackCall.Error("Status: " + "EMDK意外关闭!请关闭并重新启动应用程序.");
    }

    @Override
    public void onConnectionChange(ScannerInfo scannerInfo, BarcodeManager.ConnectionState connectionState) {
        String status;
        String scannerName = "";

        String statusExtScanner = connectionState.toString();
        String scannerNameExtScanner = scannerInfo.getFriendlyName();

        if (deviceList.size() != 0) {
            scannerName = deviceList.get(scannerIndex).getFriendlyName();
        }

        if (scannerName.equalsIgnoreCase(scannerNameExtScanner)) {//忽略大小写

            switch (connectionState) {
                case CONNECTED:
                    deInitScanner();
                    initScanner();
                    setTrigger();
                    setDecoders();
                    break;
                case DISCONNECTED:
                    deInitScanner();
                    break;
            }

            status = scannerNameExtScanner + ":" + statusExtScanner;
            onBackCall.OnStart(status);
        } else {
            status = scannerNameExtScanner + ":" + statusExtScanner;
            onBackCall.OnStart(status);
        }
    }

    @Override
    public void onData(ScanDataCollection scanDataCollection) {
        if ((scanDataCollection != null) && (scanDataCollection.getResult() == ScannerResults.SUCCESS)) {
            ArrayList<ScanDataCollection.ScanData> scanData = scanDataCollection.getScanData();
            for (ScanDataCollection.ScanData data : scanData) {
                String dataString = data.getData();
                ViseLog.i("onData OnSuccess = " + dataString);
                if (bContinuousMode) {
                    onBackCall.OnContinuous(dataString);
                } else {
                    onBackCall.OnSuccess(dataString);
                }
            }
        }
    }

    @Override
    public void onStatus(StatusData statusData) {
        StatusData.ScannerStates state = statusData.getState();
        switch (state) {
            case IDLE://关闭
                if (bContinuousMode) {
                    try {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        scanner.read();
                    } catch (ScannerException e) {
                        onBackCall.Error(e.getMessage());
                    }
                }
                break;
        }
    }

    public void startScan(boolean bContinuousMode) {

        if (scanner == null) {
            initScanner();
        }

        if (scanner != null) {
            try {
                if (scanner.isEnabled()) {
                    // Submit a new read.
                    this.bContinuousMode = bContinuousMode;
                    scanner.read();
                } else {
                    onBackCall.Error("Status: 扫描仪未启用");
                }
            } catch (ScannerException e) {
                onBackCall.Error("Status: " + e.getMessage());
            }
        }

    }

    public void stopScan() {
        if (scanner != null) {
            try {
                // Reset continuous flag
                bContinuousMode = false;
                // Cancel the pending read.
                scanner.cancelRead();
            } catch (ScannerException e) {
                onBackCall.Error("Status: " + e.getMessage());
            }
        }
    }

    private void deInitScanner() {
        if (scanner != null) {
            try {
                scanner.cancelRead();
                scanner.disable();
            } catch (Exception e) {
                onBackCall.Error("Status: " + e.getMessage());
            }
            try {
                scanner.removeDataListener(this);
                scanner.removeStatusListener(this);
            } catch (Exception e) {
                onBackCall.Error("Status: " + e.getMessage());
            }
            try {
                scanner.release();
            } catch (Exception e) {
                onBackCall.Error("Status: " + e.getMessage());
            }

            scanner = null;
        }
    }

    private void initScanner() {
        if (scanner == null) {
            if ((deviceList != null) && (deviceList.size() != 0)) {
                scanner = barcodeManager.getDevice(deviceList.get(scannerIndex));
                Log.i("huangmin", "deviceListdata" + deviceList.get(scannerIndex));
            } else {
                onBackCall.Error("Status: " + "未能获得指定的扫描仪设备!请关闭并重新启动应用程序。");
                return;
            }
            if (scanner != null) {
                scanner.addDataListener(this);
                scanner.addStatusListener(this);
                try {
                    scanner.enable();
                } catch (ScannerException e) {
                    onBackCall.Error("Status: " + e.getMessage());
                }
            } else {
                onBackCall.Error("Status: " + "未能初始化扫描设备.");
            }
        }
    }

    private void setTrigger() {

        if (scanner == null) {
            initScanner();
        }
        if (scanner != null) {
            scanner.triggerType = Scanner.TriggerType.SOFT_ALWAYS;//软件触发
        }
    }

    private void setDecoders() {

        if (scanner == null) {
            initScanner();
        }

        if ((scanner != null) && (scanner.isEnabled())) {
            try {
                ScannerConfig config = scanner.getConfig();
                // Set EAN8
                config.decoderParams.ean8.enabled = true;

                // Set EAN13
                config.decoderParams.ean13.enabled = true;

                // Set Code39
                config.decoderParams.code39.enabled = true;

                //Set Code128
                config.decoderParams.code128.enabled = true;

                scanner.setConfig(config);
            } catch (ScannerException e) {
                onBackCall.Error("Status: " + e.getMessage());
            }
        }
    }

    private void enumerateScannerDevices() {

        if (barcodeManager != null) {

            List<String> friendlyNameList = new ArrayList<String>();
            int spinnerIndex = 0;

            deviceList = barcodeManager.getSupportedDevicesInfo();

            if ((deviceList != null) && (deviceList.size() != 0)) {

                Iterator<ScannerInfo> it = deviceList.iterator();
                while (it.hasNext()) {
                    ScannerInfo scnInfo = it.next();
                    friendlyNameList.add(scnInfo.getFriendlyName());
                    if (scnInfo.isDefaultScanner()) {
                        defaultIndex = spinnerIndex;
                    }
                    ++spinnerIndex;
                }
            } else {
                onBackCall.Error("Status: " + "未能获得支持的扫描器设备列表!请重启设备.");
            }
        }
    }

    private void setSelection(int Postion) {
        scannerIndex = Postion;
        deInitScanner();
        initScanner();
        setTrigger();
        setDecoders();
    }

    public void EndRelease() {
        deInitScanner();

        // Remove connection listener
        if (barcodeManager != null) {
            barcodeManager.removeConnectionListener(this);
            barcodeManager = null;
            deviceList = null;
        }

        // Release the barcode manager resources
        if (emdkManager != null) {
            emdkManager.release(EMDKManager.FEATURE_TYPE.BARCODE);
        }
        deInitScanner();

        // Remove connection listener
        if (barcodeManager != null) {
            barcodeManager.removeConnectionListener(this);
            barcodeManager = null;
        }

        // Release all the resources
        if (emdkManager != null) {
            emdkManager.release();
            emdkManager = null;
        }
        if (profileManager != null)
            profileManager = null;

        if (emdkManager2 != null) {
            emdkManager2.release();
            emdkManager2 = null;
        }
    }
}
